#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

#include "util.h"

char *LogFileName;

void writelog(int end, int rc, const char *fmt, ...) {
  static FILE *filelog=NULL;
  char buf[MAXSTRLEN+1];
  va_list ap;
  va_start(ap, fmt);
#ifdef  HAVE_VSNPRINTF
  vsnprintf(buf, MAXSTRLEN, fmt, ap);       /* safe */
#else
  vsprintf(buf, fmt, ap);                   /* not safe */
#endif
  if(filelog==NULL) {
    if(LogFileName==NULL || (filelog=fopen(LogFileName,"w"))==NULL) {
                filelog=stderr;
    }
  }
  fputs(buf,filelog);
  if(end) {
    fflush(filelog);
    fclose(filelog);
    exit(rc);
  }
}

void *Malloc(int size) {
  void *r; 

  if(size<=0) {
    writelog(TRUE,MALLOC_RC,"malloc invalid size");
  }
  if((r=malloc(size))==NULL) {
    writelog(TRUE,MALLOC_RC,"malloc failed");
  }
	
   memset(r, 0, size);
  return r;
}

void Free(void *p) {
  free(p);
  p = NULL;
}

FILE *Fopen(const char *filename, const char *mode) {
        FILE    *fp;

        if ( (fp = fopen(filename, mode)) == NULL)
          writelog(TRUE,FOPEN_RC," failed fopen for %s\n", filename);

        return(fp);
}

void *Mmap(const char *filename, const char *mode) {
	void *ptr;
	struct stat     statbuf;
	int fd;

        FILE* fp = Fopen(filename, mode);
	fd=fileno(fp);

        if (fstat(fd, &statbuf) < 0)  /* need size of input file */
                writelog(TRUE,FSTAT_RC,"fstat error");

        if ((ptr = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0)) == 
	     MAP_FAILED) {
 	     writelog(TRUE,MMAP_RC,"mmap error for input");
	}
	return ptr;
}


size_t Fread (void * ptr, size_t size, size_t count, FILE * stream){
	
	size_t r;
	
	if( !(r=fread(ptr, size, count, stream)) ){
		writelog(TRUE,FREAD_RC,"failed fread");
	}
	
	return r;
}

char *Strdup(char *p) {
  char *r;
  if(p==NULL) {
    writelog(TRUE,STRDUP_RC,"strdup invalid pointer");
  }
  if((r=strdup(p))==NULL) {
    writelog(TRUE,STRDUP_RC,"strdup");
  }
  return r;
}


bool pow_of_two(int i){
	
	int d=i/2;
	int r=i%2;
		
	if(r!=0) return FALSE;
	
	if(d==1) return TRUE;
	
	return pow_of_two(d);
	
}
